_____ _____ ___ /_______ __ / / / __/ ___/ _ /_/ // /_ / /__ _\__, / \__/ \___/ /____/ytc98.cjb.net Target Info ~"~"~"~"~"~ Name : Aareus IconCommander URL : http://www.telusplanet.net/public/brbi/aareus/software/ Protection : Serial protection, crippled in unregistered version. Introduction ~"~"~"~"~"~" Hi there! At first looks, I thought that this program is going to be a tough one, since the buttons, windows and other stuffs doesn't look normal to me. But, after disassembling it, I realized that it uses custom controls, written in VC++ (this is what IDA gave me). From their site, you can obtain the source codes for writing custom controls in win32asm. Okay, tutorial time ;). Tools Needed ~"~"~"~"~"~" Softice v3.x IDA Pro v3.x Asm compiler (for writing the keygen - optional) The Essay ~"~"~"~"~ First of all, this program breaks on hmemcpy, so using it and tracing through, you will land yourself right after a call to SendMessageA at .text:1000679Fh. Notice that there's two more SendMessageA calls, so, simple deduction will tell you that these are the functions to get your text from the registration dialog. After the third SendMessageA call, it takes the first letter of your name and compares it with zero, followed by a conditional jump, jz. This routine checks if you entered anything into the 'Name' edit box, jumping to 'bad serial' if you didn't put in any. Obviously, it only does the check to your name, which means the 'Company' edit box can be left empty. Next, you see it pushing the offsets of your name, company and password. Then followed by a call to 1000B9F0h. Hmm...fishy. Lets take a look inside this call. Well, you find three calls to GlobalAlloc, then you find out that the details you entered are being copied around. If you use IDA and look at this section, you'll see call _memcpy. Isn't IDA just simply amazing? ;) After all this copying around, you see another call, which is followed by three calls to GlobalFree. Yup, this call must be the password generating routine ;). So, what are we waiting for?? Step into the call, and whoa! Lots and lots of codes! Don't worry, just keep tracing =). Lets see, a call to GlobalAlloc, then a RegOpenQueryExA, two RegQueryValueExA and three lstrcpyA. Hmm..then you see your details are being manipulated around. Here's a short snippet. _text_1000BC32: mov esi, [ebp+var_38] ; put location of password in esi _text_1000BC35: mov al, [esi] ; put first letter of password in al cmp al, 0 ; cmp with 0 jz _text_1000BC49 ; jump if 0, meaning password has ended sub al, 14h ; subtract 14h from your password mov [esi], al ; replace letter with the new value inc esi ; increase pointer of password jmp _text_1000BC35 ; loop _text_1000BC49: mov eax, [ebp+var_38] ; put location of password in eax push eax ; push location of password call _atoi ; converts decimal string to hex in eax OK, looks simple enough. Subtracts every character of your password with 14h, then convert it to hex. Meaning, your converted password MUST be a decimal string (because of the call to _atoi). So, what about your UNCONVERTED password? It would be decimal number + 14h. So, lets find out the range of alphabets which is valid for use as password. The hex value for the smallest digit value, 0 (zero) is 30h, so, 30h+14h=68h, which is D. The hex value for the biggest digit value, 9 (nine) is 39h, so 39h+14h=77h, which is M. So our password consists of letters ranging from D to M. OK, lets continue with the routine. call _atoi ; convert decimal string to hex in eax add esp, 4 ; move stack pointer mov [ebp+var_20], eax ; saves converted password mov eax, [ebp+var_14] ; takes location of name mov [ebp+var_1C], eax ; saves it mov eax, [ebp+var_C] ; takes location of company mov [ebp+var_30], eax ; saves it mov eax, [ebp+var_8] ; takes location of string "DefaultIcon" mov [ebp+var_4], eax ; saves it mov eax, [ebp+var_20] ; moves eax with converted password rol eax, 3 ; rotate left 3 bits mov edi, [ebp+var_4] ; takes location of string "DefaultIcon" mov edx, [edi] ; move hex values to edx xor eax, edx ; xor it with the rol-ed converted password ror eax, 7 ; rotate right the result 7 bits mov esi, [ebp+var_30] ; takes location of company mov edx, [esi] ; moves hex values to edx ror edx, 2 ; rotate right it 2 bits xor eax, edx ; xor it with the result from previous calculation on password mov edi, [ebp+var_1C] ; takes location of your name cmp eax, [edi] ; compare the calculated result with hex values of name jz _text_1000BC95 ; jump to 'good_guy' if equal If you don't know what ror, rol and xor are for, you better check with your asm manual. I'm not going to explain such matters here ;). Anyway, back to our code. Here's a summary of what it is doing. 1. Subtract 14h from each letter of your password to get decimal string. 2. Convert the decimal string to a hex value at eax. 3. ROL the hex value of your converted password 3 bits. 4. XOR it with hex values of the first 4 bytes in the string "DefaultIcon". 5. ROR the result 7 bits. 6. Takes the first 4 bytes of your company and ROR it 2 bits. 7. The result is XORed with result from step 5. 8. Final result is compared with the first 4 letters of your name. Hmm...looks like there's some reversing to do ;). Beginning this part, I would like to express my thanks to josephCo of MexElite for helping me with this part. Ok, so lets start thinking. The opposite of ROL is ROR, and vice versa. The opposite of XOR is also XOR. Now, start working the calculation routine the other way round. 1. Result in step 8 is your name, which is calculated from the XORed values of results from step 5 and step 6. The result of step 6 is a constant and doesn't need any reversing. By XORing our name with result of step 6 will give us result for step 5. 2. For the constant, it's RORing the first 4 bytes of your company 2 bits. 3. ROLing 7 bits the result of step 5 will give us result for step 4. 4. XORing it with hex values from first 4 bytes of string "DefaultIcon" will give us result for step 3. 5. RORing this result 3 bits will give us our hex value of our converted password. 6. Converting this hex value to string and adding 14h to each hex value will give us our valid serial. Final Notes ~"~"~"~"~"~ Once again, I would really want to express my thanks to josephCo for guiding and helping me in reversing this calculation routine. josephCo, you're the best! ;) Well, that's all for now. ytc_, signing off... Author of Aareus Icon Commander, Arel Clayton, for allowing me to put up this tutorial here. (I really appreciate this, thank you very very much). Group greets : Phrozen Crew, MiB, MASSiVE, DEViOUS, ECG, PCG, HERITAGE, tNO, RAiD, WWC, MexElite Personal greets : Iczelion, Kwai_Lo, Cr-S, hutch-, virogen, hayras, JosephCo, Flu[X], Fresh--, blorght, immoral, Sleepers, Pr0phecy, Neural_N, KingGatso, ufk, _masta_, C4ffeine, Icecream, WKT_White, Sixx, +Malattia, +Cruehead, Icedragon, The+Q, HarvestR, BuLLeT, +gthorne (long time no see ;)), Ghiribizzo, Plushmm, Cali', _Hak_, zoltan, [Xorolc], [aLC], raza, Ousir, infamous, Mem_Lost, Quantico, night_mastah, [Kiyone], Mister Fanatic, MisterE, Iceman, and not to forget to those who shed light on me about cracking/reverse engineering (+ORC, Fravia+, Sandman, Mammon) Channel greets : #cracking4newbies, #cracking, #win32asm, #cracking_forum (If I miss anyone out or you don't like the order of my greets, please forgive me) ytc_